package com.example.ljy;

import android.Manifest;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.chrischen.waveview.WaveView;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class StudyActivity extends AppCompatActivity {
    Handler recordHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 1:
                    Double d= (Double) msg.obj;
                    DecimalFormat df = new DecimalFormat("0.0");

                    YinLiang.setText("音量:  "+df.format(d)+"");

                  //  waveView.putValue(Integer.valueOf(String.valueOf(msg.obj)));
                    break;
                case 2:
                   // File externalFilesDir = getApplication().getExternalFilesDir(Environment.DIRECTORY_MUSIC);
                    //FILE_NAME = externalFilesDir.getPath()+msg.obj+".mp3";

                    FILE_NAME = getApplication().getFilesDir().getAbsolutePath()+msg.obj+".mp3";
                    File file = new File(FILE_NAME);
                    if(file.exists()){
                        file.delete();
                    }
                    resid = assResources.get(msg.obj);
                    //waveView.putValue(msg.arg2);
                default:
                    break;
            }
        }
    };
    int resid;
    int index = 0;
    TextView wordtv;
    Button next_btn;
    TextView YinLiang;
    Button start_record;
    Button stop_record;
    Button your_btn;
    Button standard_b;
    TextView textViewFs;
    private String FILE_NAME = "";
    private String Stard_FILE_NAME = "";
    List<String> strings = new ArrayList<>();
    Map<String,Integer> assResources= new HashMap<>();
    /*private List<String> stardlists;*/
    WaveView waveView;
    //private static final String FILE_NAME = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC) + File.separator + "test.pcm";

    private AudioRecord audioRecord = null;
    private int recordBufsize = 0;
    private boolean isRecording = false;
    private Thread recordingThread;
    Random numList = new Random();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.study_layout);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1000);
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 2000);
        }
        if (ContextCompat.checkSelfPermission(this,Manifest.permission.CAPTURE_AUDIO_OUTPUT) != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 3000);
        }
       /* if (Build.VERSION.SDK_INT >= 30){
            if (!Environment.isExternalStorageManager()){
                Intent getpermission = new Intent();
                getpermission.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                startActivity(getpermission);
            }
        }*/
        createAudioRecord();
        try {
            initData();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //getResources().getAssets().
        initViews();

    }

    private void initData() throws IOException {
       /* AssetManager assetManager = this.getAssets();
        String[] strings = assetManager.list("");
        for (int s = 0; s < strings.length; s++) {
            Log.e(TAG, "initData:"+strings[s] );
        }*/
        Field[] fields=R.raw.class.getFields();
        for(int i = 0; i<fields.length; i++){
            strings.add(fields[i].getName());
            Log.i("Raw Asset: ", fields[i].getName());
        }
        assResources.put("abandon",R.raw.abandon);
        assResources.put("abbreviate",R.raw.abbreviate);
        assResources.put("abbreviation",R.raw.abbreviation);
        assResources.put("ability",R.raw.ability);
        assResources.put("abnormal",R.raw.abnormal);
        assResources.put("aboard",R.raw.aboard);
        assResources.put("abolish",R.raw.abolish);
        assResources.put("abort",R.raw.abort);
        assResources.put("abortion",R.raw.abortion);
        assResources.put("about",R.raw.about);
        assResources.put("above",R.raw.above);
        assResources.put("abrupt",R.raw.abrupt);
        assResources.put("absence",R.raw.absence);
        assResources.put("absent",R.raw.absent);

    }

    void initViews(){
        createAudioRecord();
        wordtv = findViewById(R.id.word);
        wordtv.setText(strings.get(0));
        resid = R.raw.abandon;
        next_btn = findViewById(R.id.next_word);
        next_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                index = index+1;
                if(index<strings.size()){
                    wordtv.setText(strings.get(index));
                    Message message = recordHandler.obtainMessage();
                    message.what = 2;
                    message.obj = strings.get(index);
                    recordHandler.sendMessage(message);
                }else {
                    index = 0;
                }
            }
        });
        YinLiang = findViewById(R.id.yin_liang);
        your_btn= findViewById(R.id.play_your_case);
        standard_b = findViewById(R.id.play_standard_case);
        textViewFs = findViewById(R.id.fenshu);
        stop_record = findViewById(R.id.stop_reclord);
        start_record = findViewById(R.id.start_reclord);
        waveView = findViewById(R.id.waweView);
        start_record.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //isRecording = true;
                startRecord();
                textViewFs.setText("您的分数为:");
            }
        });
        stop_record.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopRecord();
                int num =  numList.nextInt(30) + 50 ;
                textViewFs.setText("您的分数为:"+num);
            }
        });
        your_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PlayRecord();
            }
        });
        standard_b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //todo
                MediaPlayer mediaPlayer = MediaPlayer.create(StudyActivity.this,resid);
                mediaPlayer.start();

              /*  FILE_NAME = getResources().getResourceName(R.raw.abandon);
                PlayRecord();
*/
            }
        });
    }
    private void startRecord() {
        if (isRecording) {
            return;
        }
        isRecording = true;
        if(audioRecord== null){
            createAudioRecord();
            Log.e("audioRecordTest", "初始化失败");
            //return;
        }
        audioRecord.startRecording();
        Log.i("audioRecordTest", "开始录音");
        recordingThread = new Thread(() -> {
            byte data[] = new byte[recordBufsize];
            if(FILE_NAME==null || FILE_NAME.isEmpty()){
              /*  File externalFilesDir = getApplication().getExternalFilesDir(Environment.DIRECTORY_MUSIC);
                FILE_NAME = externalFilesDir.getPath()+strings.get(index)+".mp3";*/
                FILE_NAME = getApplication().getFilesDir().getAbsolutePath()+strings.get(index)+".mp3";
                File file = new File(FILE_NAME);
                if(file.exists()){
                    file.delete();
                }
            }
            File file = new File(FILE_NAME);
            FileOutputStream os = null;
            try {
                if (!file.exists()) {
                    file.createNewFile();
                    Log.i("audioRecordTest", "创建录音文件->" + FILE_NAME);
                }
                os = new FileOutputStream(file);
            } catch (Exception e) {
                e.printStackTrace();
            }
            int read;
            if (os != null) {
                while (isRecording) {
                    double v = calculateVolume(data);
                    Message message = recordHandler.obtainMessage();
                    message.what = 1;
                    message.obj = v;
                    recordHandler.sendMessage(message);
                    read = audioRecord.read(data, 0, recordBufsize);
                    if (AudioRecord.ERROR_INVALID_OPERATION != read) {
                        try {
                            os.write(data);
                            Log.i("audioRecordTest", "写录音数据->" + read);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }catch (RuntimeException e){
                e.printStackTrace();

            }
        });
        recordingThread.start();
    }
    private double calculateVolume(byte[] buffer){

        double sumVolume = 0.0;

        double avgVolume = 0.0;

        double volume = 0.0;

        for(int i = 0; i < buffer.length; i+=2){
            int v1 = buffer[i] & 0xFF;

            int v2 = buffer[i + 1] & 0xFF;

            int temp = v1 + (v2 << 8);// 小端

            if (temp >= 0x8000) {
                temp = 0xffff - temp;

            }

            sumVolume += Math.abs(temp);

        }

        avgVolume = sumVolume / buffer.length / 2;

        volume = Math.log10(1 + avgVolume) * 10;


        return volume;

    }
    private void createAudioRecord() {
        recordBufsize = AudioRecord
                .getMinBufferSize(16000,
                        AudioFormat.CHANNEL_IN_MONO,
                        AudioFormat.ENCODING_PCM_16BIT);
        Log.i("audioRecordTest", "size->" + recordBufsize);
        audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                16000,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT,
                recordBufsize*2);
    }
    private void stopRecord() {
        isRecording = false;
        if (audioRecord != null) {
            audioRecord.stop();
            Log.i("audioRecordTest", "停止录音");
            audioRecord.release();
            audioRecord = null;
            recordingThread = null;
        }
    }

    /**
     * 播放录音
     */
    public void PlayRecord() {
        new Thread(playPCMRecord).start();
    }

    private Runnable playPCMRecord = new Runnable() {
        @Override
        public void run() {
            int bufferSize = AudioTrack.getMinBufferSize(8000,
                    AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
            AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                    8000, AudioFormat.CHANNEL_OUT_STEREO,
                    AudioFormat.ENCODING_PCM_16BIT, recordBufsize, AudioTrack.MODE_STREAM);
            FileInputStream fis = null;
            try {
                audioTrack.play();
                fis = new FileInputStream(FILE_NAME);
                byte[] buffer = new byte[recordBufsize];
                int len = 0;
                while ((len = fis.read(buffer)) != -1) {
                    Log.d("test", "playPCMRecord: len " + len);
                    audioTrack.write(buffer, 0, len);
                }

            } catch (Exception e) {
                Log.e("test", "playPCMRecord: e : " + e);
            } finally {
                if (audioTrack != null) {
                    audioTrack.stop();
                    audioTrack = null;
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    };


}
